Skip to content

refactor(plugin/claude-code): extract installer wrapper to checked-in file#2024

Closed
t0saki wants to merge 2 commits into
volcengine:mainfrom
t0saki:refactor/claude-plugin-wrapper-rc
Closed

refactor(plugin/claude-code): extract installer wrapper to checked-in file#2024
t0saki wants to merge 2 commits into
volcengine:mainfrom
t0saki:refactor/claude-plugin-wrapper-rc

Conversation

@t0saki
Copy link
Copy Markdown
Collaborator

@t0saki t0saki commented May 13, 2026

Summary

Same refactor as #2023 (in flight), applied to the claude-code-memory-plugin installer.

Before

The installer-emitted claude() wrapper was inlined as a marker-delimited block inside the user's ~/.zshrc / ~/.bashrc. Upgrade flow used awk to strip the existing block and append a new one. Drawbacks:

  • ~16 lines of shell function body in the user's rc (the kind of thing you'd cringe at when reading your own rc).
  • Footgun: if the END marker got accidentally deleted from the rc (manual edit, partial-corruption, …), the next install's awk strip would drop everything from the BEGIN marker to EOF.
  • The wrapper body lived as a cat >> "$RC" <<EOF-with-escaped-$ heredoc inside install.sh — annoying to review, annoying to syntax-check.

After

  • Wrapper body extracted to examples/claude-code-memory-plugin/setup-helper/wrapper.sh as a checked-in source file. Real syntax highlighting, real diffable history.
  • The user's shell rc gets a single one-line source hook that points at the wrapper source inside the cloned plugin checkout ($REPO_DIR/examples/claude-code-memory-plugin/setup-helper/wrapper.sh).
  • Updates ride for free on the installer's existing git fetch + reset --hard step. No "re-run installer to refresh the wrapper" path.
  • ~/.zshrc OV-plugin block: ~16 lines → 3 lines (begin marker + source hook + end marker).
  • Marker-replacement on re-install only triggers the legacy-cleanup path once — when upgrading from the pre-split installer that inlined the full wrapper.

Same pattern as #2023

This is the same shape applied to the codex installer in #2023 (open). I'm proposing it as a separate PR so the claude-code change can be reviewed / merged independently — there's no functional dependency between the two.

Behavior preserved

The wrapper itself is byte-for-byte the same claude() function as before (jq to read ovcli.conf → inject OPENVIKING_URL / OPENVIKING_API_KEY → exec claude). This PR only changes where the wrapper code lives.

Test plan

  • bash -n examples/claude-code-memory-plugin/setup-helper/install.sh passes
  • bash -n examples/claude-code-memory-plugin/setup-helper/wrapper.sh passes
  • Running the installer over an existing pre-split install correctly strips the legacy block and replaces it with the 3-line source hook
  • source ~/.zshrc && type claude shows the wrapper loaded from the standalone file
  • claude invocation still injects OPENVIKING_URL / OPENVIKING_API_KEY from ovcli.conf

t0saki added 2 commits May 13, 2026 21:43
The installer-emitted claude() wrapper had been inlined as a
marker-delimited block in the user's ~/.zshrc / ~/.bashrc. Every upgrade
required the awk-strip-and-append dance, the inline noise was hostile
to anyone reading their own rc, and there was a known footgun: if the
END marker got hand-deleted from the rc, the next install's awk-strip
would drop everything from the BEGIN marker to EOF.

Switch to the standard pyenv / nvm / fnm pattern, mirroring what the
codex-memory-plugin installer now does (see volcengine#2023):

- Wrapper body lives in its own file at ~/.openviking/claude-plugin.rc.sh
  (path overridable via OPENVIKING_CLAUDE_WRAPPER_RC). Full overwrite on
  every install — no marker logic inside the wrapper file itself.

- The user's shell rc gets a single one-line source hook, still
  marker-wrapped for clean uninstall:

    # >>> openviking claude-code memory plugin >>>
    [ -f "$HOME/.openviking/claude-plugin.rc.sh" ] && . "..."
    # <<< openviking claude-code memory plugin <<<

  Content is constant across installs, so the marker-replacement logic
  only triggers the legacy-cleanup path once (when upgrading from a
  pre-rc-split install that inlined the full claude() function body).

User-visible improvements:

- ~/.zshrc OV-plugin block: ~16 lines of wrapper body → 3 lines.
- Wrapper body is a real file you can `cat` / `diff` / restore from
  source control; no need to re-run the installer to inspect it.
- Uninstall: `rm ~/.openviking/claude-plugin.rc.sh` + delete the 3-line
  marker block.
- The END-marker corruption footgun is gone, since the marker block
  content is bytestring-stable and the awk-strip only runs when both
  markers are present anyway.

No behavior change to the wrapper itself (still pulls url/api_key from
ovcli.conf via jq).
…per/wrapper.sh

Squash-style follow-up to the previous rc-split commit on this branch:
now that the wrapper lives in its own file conceptually, just check it
in at examples/claude-code-memory-plugin/setup-helper/wrapper.sh and
have the user's shell rc source it directly from the cloned plugin
checkout. No copy step, no heredoc dance in install.sh.

Why this is better than the previous approach (wrapper body embedded as
a heredoc in install.sh, written to a copy in ~/.openviking):

- Wrapper is a real reviewable file. Diffs show `+ claude() { ... }`,
  not "+ heredoc lines that produce the wrapper".
- Updates ride on the installer's existing `git fetch + reset --hard`
  step — no separate "re-run installer to refresh the copy" path.
- One less source of truth (no $HOME copy that can drift from the
  installer's intent).
- Uninstall: `rm ~/.openviking/openviking-repo`; the source hook in the
  rc silently no-ops via `[ -f ... ] && .`.

The previous commit on this branch already shrunk the rc block from
~16 inline lines to 3 (marker + source hook + marker). This commit just
moves the wrapper body from "embedded in installer" to "checked into the
repo at a stable path", with no behavior change to the wrapper itself.
@github-actions
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

2023 - Partially compliant

Compliant requirements:

  • N/A (this PR is a separate refactor)

Non-compliant requirements:

  • Allow empty api_key for unauthenticated local OV
  • Conditionally render .mcp.json based on api_key presence
  • Drop bearer_token_env_var when no api_key
  • Add auth mode reporting in installer footer

Requires further human verification:

  • N/A
⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🏅 Score: 95
🧪 No relevant tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ No major issues detected

@github-actions
Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

@t0saki
Copy link
Copy Markdown
Collaborator Author

t0saki commented May 13, 2026

Superseded by #2026 (combined codex + claude-code wrapper refactor).

@t0saki t0saki closed this May 13, 2026
@github-project-automation github-project-automation Bot moved this from Backlog to Done in OpenViking project May 13, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the claude-code-memory-plugin installer to stop inlining a large claude() shell wrapper into the user’s shell rc file, and instead source a checked-in wrapper file from the cloned plugin checkout.

Changes:

  • Added a standalone claude() wrapper at examples/claude-code-memory-plugin/setup-helper/wrapper.sh.
  • Updated the installer to write a marker-delimited rc snippet that sources the wrapper file from $REPO_DIR instead of embedding the full function body.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
examples/claude-code-memory-plugin/setup-helper/wrapper.sh New checked-in claude() wrapper meant to be sourced from the user’s shell rc.
examples/claude-code-memory-plugin/setup-helper/install.sh Installer now writes a small source-hook block into the user’s shell rc instead of inlining the wrapper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +192 to +195
SOURCE_HOOK="[ -f \"$WRAPPER_SRC\" ] && . \"$WRAPPER_SRC\""
SOURCE_BLOCK="$MARKER_BEGIN
$SOURCE_HOOK
$MARKER_END"
Comment on lines +204 to 211
info "Replacing openviking source hook in $RC"
# Strip existing block (whether it's the new one-liner or an old
# inline-wrapper block from a previous version).
awk -v b="$MARKER_BEGIN" -v e="$MARKER_END" '
$0 == b {skip=1; next}
$0 == e {skip=0; next}
!skip
' "$RC" > "$RC.tmp" && mv "$RC.tmp" "$RC"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants